{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "aa8322cc",
   "metadata": {},
   "source": [
    "### 本周内容\n",
    "1. 函数的定义\n",
    "2. 如何使用函数\n",
    "3. 函数的返回值\n",
    "4. 使用注释改进文档\n",
    "5. 传递任意数量的实参\n",
    "6. 函数与模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "50ef991d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数：\n",
    "# 写 def 定义函数的第一步\n",
    "# 写定义函数的名称: def function_name:遵循变量名称定义的规则——只能用数字下划线，内置变量名不可使用，不能以数字开头\n",
    "# 函数名称后加上\"():\"  def function_name():  ===> f(x) = 2x\n",
    "\n",
    "# 书写函数体：\n",
    "# 1.函数的注释\n",
    "# 2.写函数的具体操作（函数体）\n",
    "# 3.注意：函数也是需要有tab键的间距\n",
    "\n",
    "# 使用函数(函数的调用)：\n",
    "# 1.function_name()\n",
    "\n",
    "\n",
    "def fib(n):    # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < n:\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "99f94398",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "fib(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "5bc3dd54",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function fib in module __main__:\n",
      "\n",
      "fib(n)\n",
      "    Print a Fibonacci series up to n.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(fib)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "7ec22494",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "# 尝试：写一个实现hello world的函数\n",
    "def meet():\n",
    "    \"\"\"打印hello world\"\"\"\n",
    "    print(\"hello world\")\n",
    "meet()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "026d9e7b",
   "metadata": {},
   "source": [
    "#### 思考函数存在的意义\n",
    "> 1.可以通过调用函数的方式实现某个功能，使用人不需要考虑函数代码内容\n",
    ">> 2.节省时间，提升应用的效率\n",
    ">>> 3.函数一旦定义，就可按照一定的规则重复使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9b7a381e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Provide a word to search for vowels:Juicy\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'i', 'u'}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "f1317d93",
   "metadata": {},
   "outputs": [],
   "source": [
    "def search4vowels(word):\n",
    "    \"\"\"\n",
    "    打印文本中出现的元音字母\n",
    "    请输入你想要查询的文本内容\n",
    "    \"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    found = vowels.intersection(set(word)) # 交集运算\n",
    "    print(found) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d63cf6ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search4vowels in module __main__:\n",
      "\n",
      "search4vowels(word)\n",
      "    打印文本中出现的元音字母\n",
      "    请输入你想要查询的文本内容\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(search4vowels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "766325e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'i', 'u'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"Juicy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "a5c20747",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"Para\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe827d82",
   "metadata": {},
   "source": [
    "#### 函数的参数\n",
    "> 1. 形式参数（形参）\n",
    ">> 1. 在定义过程中，函数的参数为形式参数\n",
    ">> 2.形式参数是虚拟的，不占用空间的\n",
    "> 2. 实际参数（实参）\n",
    ">> 1. 调用函数过程中，函数的参数为实际参数\n",
    ">> 2.调用函数时，形式参数被分配空间，成为实际参数并应用起来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "06e3a2a0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数\n",
    "def greet_user(username):    \n",
    "    \"\"\"显示简单的问候语，输入你的名字\"\"\"    \n",
    "    print(\"hello,\"+ username.title()+\"!\") "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "615b553c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Juicy!\n"
     ]
    }
   ],
   "source": [
    "# 调用函数：　username　= \"Juicy\"\n",
    "greet_user(\"Juicy\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37289f3c",
   "metadata": {},
   "source": [
    "* 当参数不止一个时：\n",
    "> 1. 位置参数(positional argument)\n",
    ">> 1. 形式参数有多个值，如果实际参数直接赋值，要按照形式参数的先后顺序，这种方式称：位置参数赋值\n",
    ">> 2.在调用函数过程中需要考虑如下：\n",
    ">>> 1. 考虑位置\n",
    ">>> 2.考虑个数\n",
    "> 2. 关键字参数\n",
    ">> 1. 在调用函数时使用，我们直接在实参中 用赋值的方式去定义形参\n",
    ">> 2.不需要考虑顺序，因为赋值已经确定了形式参数的值\n",
    "> 3. 默认参数\n",
    ">> 1. 默认参数写在 形式参数中（预计有大量的调用会使用到的值，可以预先设置）\n",
    ">> 2.默认参数存在的话，实际调用过程中可以省略赋值的过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "81698964",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "Mycat's name is 大腕.\n"
     ]
    }
   ],
   "source": [
    "# 请注意，有两个参数\n",
    "def describe_pet (animal_type,pet_name):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \"+ animal_type + \".\")\n",
    "    print(\"My\"+ animal_type + \"'s name is \" + pet_name.title()+\".\")\n",
    "describe_pet(\"cat\",\"大腕\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "34781149",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "Mycat's name is 大腕.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数\n",
    "describe_pet(animal_type=\"cat\",pet_name=\"大腕\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "254364dc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a cat.\n",
      "Mycat's name is 双子.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(pet_name=\"双子\",animal_type=\"cat\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "9443a0bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数(写在形式参数中的)\n",
    "def describe_pet(pet_name,animal_type=\"cat\"):\n",
    "    \"\"\"显示宠物信息，animal_type 的默认值 'cat'\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "004afb19",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a  cat.\n",
      "My cat's name is 双子.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\" cat\",\"双子\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7332bbc",
   "metadata": {},
   "source": [
    "#### 实操和注意\n",
    "> 1. 关键字参数和位置参数同时使用\n",
    ">> 1.SyntaxError: positional argument follows keyword argument(位置参数需要放在关键字参数的前面)\n",
    "> 2. 默认参数和位置参数同时存在\n",
    ">> 2.SyntaxError: non-default argument follows default argument(默认参数要放在后面)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "f790bc94",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "#案例一：\n",
    "def test(x,y):\n",
    "    print(x)\n",
    "    print(y)    \n",
    "test(1,y=2) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "26a527a9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#案例二:\n",
    "def func_test(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)   \n",
    "func_test(2,1,z=3)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "fed82416",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "5\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#案例三:\n",
    "def func_test(x,z,y=3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)    \n",
    "func_test(2,3,5) "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "947d7815",
   "metadata": {},
   "source": [
    "#### 函数的返回值\n",
    "> 1.在程序开发中，有时候会希望一个函数执行结果结束后，告诉调用者一个结果，以便调用者针对具体的结果做后续的处理\n",
    "> 2.在函数中使用 return 关键字可以返回结果\n",
    "> 3.调用函数一方，可以使用变量来接收函数的返回结果\n",
    "* 注意： return 表示返回，后面的代码一律不在执行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "178300c8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "结果是：119\n"
     ]
    }
   ],
   "source": [
    "def sum(num1, num2):\n",
    "    \"\"\"\"两数求和\"\"\"\n",
    "    return num1 + num2\n",
    "# 调用函数，并使用 result 变量接受结果\n",
    "result = sum(63, 56)\n",
    "print(\"结果是：%d\" % (result))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
